package com.skyline.common.validation;

import java.io.IOException;
import java.io.InputStream;
import java.util.Locale;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.validator.Form;
import org.apache.commons.validator.Validator;
import org.apache.commons.validator.ValidatorResources;
import org.springframework.beans.FatalBeanException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
import org.springframework.util.StringUtils;
import org.xml.sax.SAXException;

/**
 * 验证框架相关配置，用于获取相关验证框架
 * 
 * @author wuqh
 * */
public class ValidationFactory implements InitializingBean {
	private static final Log LOGGER = LogFactory.getLog(ValidationFactory.class);
	private ValidatorResources validatorResources;
	private static final String ERRORS_KEY = "com.skyline.common.validation.Errors";
	
	@Override
	public void afterPropertiesSet() throws Exception {
		if (this.validatorResources == null) {
			throw new FatalBeanException(
					"Unable to locate validation configuration. Property [validationLocations] is required.");
		}
	}

	public void setValidationConfigLocations(Resource[] validationConfigLocations) {
		LOGGER.info("Loading validation configurations from ["
				+ StringUtils.arrayToCommaDelimitedString(validationConfigLocations) + "]");

		try {
			InputStream[] inputStreams = new InputStream[validationConfigLocations.length];
			for (int i = 0; i < inputStreams.length; i++) {
				inputStreams[i] = validationConfigLocations[i].getInputStream();
			}
			this.validatorResources = new ValidatorResources(inputStreams);
		} catch (IOException e) {
			throw new FatalBeanException("Unable to read validation configuration due to IOException.", e);
		} catch (SAXException e) {
			throw new FatalBeanException("Unable to parse validation configuration XML", e);
		}
	}

	public Validator getValidator(String beanName, Object bean, Errors errors) {
		Validator validator = new Validator(validatorResources, beanName);
		validator.setParameter(ERRORS_KEY, errors);
		validator.setParameter(Validator.BEAN_PARAM, bean);
		return validator;
	}

	public boolean hasRulesForBean(String beanName) {
		return hasRulesForBean(beanName, Locale.getDefault());
	}

	public boolean hasRulesForBean(String beanName, Locale locale) {
		Form form = validatorResources.getForm(locale, beanName);
		return (form != null);
	}

	public ValidatorResources getValidatorResources() {
		return validatorResources;
	}

}
